/******************************************************************************* 
 * Copyright (C) 2012-2015 Microfountain Technology, Inc. All Rights Reserved. 
 * 
 * Unauthorized copying of this file, via any medium is strictly prohibited.   
 * Proprietary and confidential
 * 
 * Last Modified: 2015-9-22 17:48:18
 ******************************************************************************/
package cn.com.xy.sms.sdk.util;

import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import cn.com.xy.sms.sdk.constant.Constant;
import cn.com.xy.sms.sdk.db.entity.SceneRule;
import cn.com.xy.sms.sdk.db.entity.Sceneconfig;
import cn.com.xy.sms.sdk.db.entity.XmlResdownload;
import cn.com.xy.sms.sdk.db.entity.XmlResdownloadManager;
import cn.com.xy.sms.sdk.log.LogManager;
import cn.com.xy.sms.sdk.net.NetUtil;

/**
 * xml资源下载对列
 * 
 * @author Administrator
 * 
 */
public class XmlDownloaderQueue extends Thread {

    public static boolean isdownloadNotWifi = false;
    XmlResdownload resdownload;// 当前正在下载的数据
    static HashSet<String> needPriorDownUrl = new HashSet<String>();// 需要优先下载的数据
    static boolean isRun = false;// 是否正在下载中

    /**
     * 添加需要优先下载的数据
     * 
     * @param url
     */
    public synchronized static void addNeedPriorDownUrlData(String url) {

        if (!StringUtils.isNull(url) && !needPriorDownUrl.contains(url)) {

            needPriorDownUrl.add(url);
        }

    }

    /**
     * 移除需要优先下载的数据
     * 
     * @param url
     */
    public synchronized static void removeNeedPriorDownUrlData(String url) {
        needPriorDownUrl.remove(url);
    }

    /**
     * 获取一个需要优先下载的数据
     * 
     * @param url
     * @return
     */
    public synchronized static XmlResdownload getNeedPriorDownUrlData() {
        Iterator<String> it = needPriorDownUrl.iterator();
        XmlResdownload res = null;
        ArrayList<String> list = new ArrayList<String>();
        while (it != null && it.hasNext()) {
            String url = it.next();
            res = XmlResdownloadManager.getNeedPriorDownUrlData(url);
            list.add(url);
            if (res != null) {
                break;
            }
        }
        // 移除目前不需要再下载的.
        needPriorDownUrl.removeAll(list);
        list.clear();
        return res;
    }

    /**
     * 获取下一个需要下载的资源
     * 
     * @return
     */
    public synchronized static XmlResdownload getNextNeedDownResdownload() {
        // 先查看是否有需要优先下载的数据
        XmlResdownload res = null;
        // 获取需要优先下载的
        res = getNeedPriorDownUrlData();
        if (res == null) {
            // 获取未下载完的,且一天之内未下载过的资源
            res = XmlResdownloadManager.getOneNotFinishDownload();
        }
        return res;
    }

    private XmlDownloaderQueue(boolean isdownloadNotWifi) {

        // this.isdownloadNotWifi = isdownloadNotWifi;
        // ResdownloadManager.updateLoadTime(resdownload);
    }

    /**
     * 执行下载资源队列线程
     * 
     * @param isdownloadNotWifi
     */
    public synchronized static void runDownResQueue(boolean isdownloadNotWifi) {
        if (isRun == false) {
            // 当队列线程序未运行时,才运行
            XmlDownloaderQueue queue = new XmlDownloaderQueue(isdownloadNotWifi);
            queue.start();
        }
    }

    public synchronized static void setRun(boolean run) {
        isRun = run;
    }

    @Override
    public void run() {
    	try {
			if (isRun == false) {
            // isRun = true;
            setRun(true);
            try {
                Thread.sleep(3000);
            } catch (Throwable e) {
//                e.printStackTrace();
                LogManager.e(Constant.TAG, "run: ",e);

            }
            XmlResdownload resdownload = getNextNeedDownResdownload();
            downLoadRes(resdownload);
            // isRun = false;
            setRun(false);
        }
		} catch (Throwable e) {
            LogManager.e(Constant.TAG, "run: " + e.getMessage(), e);
		}
    }

    /***
     * 下载资源
     * 
     * @param resdownload
     */
    private void downLoadRes(XmlResdownload resdownload) {
        if (!NetUtil.checkAccessNetWork(2)) {
            return;
        }
        if (resdownload != null) {
            try {
                this.resdownload = resdownload;
                downloadzippackage(resdownload);
            } catch (Throwable e) {
//                e.printStackTrace();
                LogManager.e(Constant.TAG, "downLoadRes: ", e);

            } finally {
                try {
                    Thread.sleep(2000);
                } catch (Throwable e) {
//                    e.printStackTrace();
                    LogManager.e(Constant.TAG, "downLoadRes: ", e);

                }
                downLoadRes(getNextNeedDownResdownload());
            }
        } else {
            isRun = false;
        }
    }

    public synchronized void downloadzippackage(XmlResdownload zippackage) {
        boolean success = false;
        InputStream dis = null;
        HttpURLConnection http = null;
        try {
            List<Sceneconfig> list = null;
            URL downUrl = new URL(zippackage.url);
            http = (HttpURLConnection) downUrl.openConnection();
            int code = http.getResponseCode();
            if (code == HttpURLConnection.HTTP_OK) {
                success = true;
                dis = http.getInputStream();
                byte[] bt = FileUtils.getInputStream(dis);
                try {
                    bt = StringUtils.uncompressGZip(bt);
                } catch (Throwable e) {
//                    e.printStackTrace();
                	LogManager.e(Constant.TAG, "XmlDownloaderQueue downloadzippackage", e);
                }
                String xmll = new String(bt, "UTF-8");
                Document docu = StringUtils.stringConvertXML(xmll, "");

                list = getSceneconfig(docu);
                SceneconfigUtil.handleSceneconfig(list, zippackage.sceneType);
            }
            XmlResdownloadManager.updateLoadTime(zippackage, System.currentTimeMillis());

        } catch (Throwable e) {
            // TODO: handle Throwable
            LogManager.e(Constant.TAG, "XmlDownLloaderQueue.downloadzippackage", e);
        } finally {
            if (success) {
                XmlResdownloadManager.updateXmlResdownloadStatus(zippackage.id, XmlResdownloadManager.FINISH);
            }
            try {
            	if (dis!=null) {
					dis.close();
				}
                if (http != null) {
                    http.disconnect();// 关闭连接
                }
            } catch (Throwable e) {
            }
        }
    }

    public static List<Sceneconfig> getSceneconfig(Document docu) {
        List<Sceneconfig> sceneconfigList = new ArrayList<Sceneconfig>();
        LogManager.i("getUrlContent", "urls!=null");
        try {
            if (docu != null) {
                NodeList items1 = docu.getElementsByTagName("Scene");

                for (int x = 0; x < items1.getLength(); x++) {
                    Sceneconfig sceneconfig = new Sceneconfig();
                    Element skinNode = (Element) items1.item(x);
                    NodeList childsNodes = skinNode.getChildNodes();
                    for (int j = 0; j < childsNodes.getLength(); j++) {
                        Node node = childsNodes.item(j); // 判断是否为元素类型
                        if (node.getNodeType() == Node.ELEMENT_NODE) {
                            String tagName = node.getNodeName();
                            if ("sceneId".equalsIgnoreCase(tagName)) {
                                sceneconfig.sceneId = XmlManager.getTextContent(node);
                            } else if ("sceneVersion".equalsIgnoreCase(tagName)) {
                                sceneconfig.sceneVersion = XmlManager.getTextContent(node);
                            }
                        }

                    }
                    NodeList sceneRuleList = skinNode.getElementsByTagName("SceneRule");
                    if (sceneRuleList != null) {
                        int size = sceneRuleList.getLength();
                        for (int k = 0; k < size; k++) {
                            SceneRule sceneRule = new SceneRule();
                            Element sceneRuleEl = (Element) sceneRuleList.item(k);
                            NodeList sceneRuleNodes = sceneRuleEl.getChildNodes();
                            for (int l = 0; l < sceneRuleNodes.getLength(); l++) {
                                Node sceneRulenode = sceneRuleNodes.item(l); // 判断是否为元素类型
                                if (sceneRulenode.getNodeType() == Node.ELEMENT_NODE) {
                                    String tagName = sceneRulenode.getNodeName();
                                    if (sceneRulenode.getNodeType() == Node.ELEMENT_NODE) {
                                        if ("sceneId".equalsIgnoreCase(tagName)) {
                                            sceneRule.scene_id = XmlManager.getTextContent(sceneRulenode);
                                        } else if ("sceneRuleVersion".equalsIgnoreCase(tagName)) {
                                            sceneRule.sceneruleVersion = XmlManager.getTextContent(sceneRulenode);
                                        } else if ("province".equalsIgnoreCase(tagName)) {
                                            sceneRule.province = XmlManager.getTextContent(sceneRulenode);
                                        } else if ("id".equalsIgnoreCase(tagName)) {
                                            sceneRule.id = XmlManager.getTextContent(sceneRulenode);
                                        } else if ("operator".equalsIgnoreCase(tagName)) {
                                            sceneRule.operator = XmlManager.getTextContent(sceneRulenode);
                                        } else if ("expire_date".equalsIgnoreCase(tagName)) {
                                            sceneRule.expire_date = XmlManager.getTextContent(sceneRulenode);
                                        } else if ("fun_call".equalsIgnoreCase(tagName)) {
                                            sceneRule.Func_call = Integer.parseInt(XmlManager.getTextContent(sceneRulenode));
                                        } else if ("fun_acc_url".equalsIgnoreCase(tagName)) {
                                            sceneRule.Func_acc_url = Integer.parseInt(XmlManager.getTextContent(sceneRulenode));
                                        } else if ("fun_reply_sms".equalsIgnoreCase(tagName)) {
                                            sceneRule.Func_reply_sms = Integer.parseInt(XmlManager.getTextContent(sceneRulenode));
                                        } else if ("fun_config".equalsIgnoreCase(tagName)) {
                                            sceneRule.Func_config = XmlManager.getTextContent(sceneRulenode);
                                        } else if ("res_urls".equalsIgnoreCase(tagName)) {
                                            sceneRule.res_urls = XmlManager.getTextContent(sceneRulenode);
                                        } else if ("s_version".equalsIgnoreCase(tagName)) {
                                            sceneRule.s_version = XmlManager.getTextContent(sceneRulenode);
                                        } else if ("scene_page_conf".equalsIgnoreCase(tagName)) {
                                            sceneRule.Scene_page_config = XmlManager.getTextContent(sceneRulenode);
                                        }

                                    }
                                }

                            }
                            sceneconfig.addSceneRule(sceneRule);
                        }
                    }
                    sceneconfigList.add(sceneconfig);
                }
            }

            LogManager.d("getUrlContent", "sceneconfigList=" ,sceneconfigList.toString());
        } catch (Throwable e) {
//            e.printStackTrace();
            LogManager.e(Constant.TAG, "getSceneconfig: ", e);

        }
        return sceneconfigList;
    }

}
